import { BIGINT_PG, INTEGER_PG, SMALLINT_PG } from "~/db.pg";
import { KeyString, KeyBool, KeyAccumulatable, KeyBigInt, KeySortable } from "~/search";

export enum ConditionType {
  MatchStr = 1001,
  MatchBool,
  MatchEnum,
  MatchInteger,
  RegExpStr,

  MatchStrOrs = 2001,
  MatchEnumOrs,
  MatchIntegerOrs,

  Time = 3001,
  Sort = 4001,
}

/** 完全匹配字符串 */
export type ConditionMatchStr<T> = {
  type: ConditionType.MatchStr;
  key: KeyString<T>;
  value: string;
  isMatch?: boolean;
};

export type ConditionMatchStrOrs<T> = {
  type: ConditionType.MatchStrOrs;
  key: KeyString<T>;
  value: string[];
  isMatch?: boolean;
};

/** 模糊匹配字符串 */
export type ConditionRegExpStr<T> = {
  type: ConditionType.RegExpStr;
  key: KeyString<T>;
  value: string;
  isMatch?: boolean;
};

/** 完全匹配布尔值 */
export type ConditionMatchBool<T> = {
  type: ConditionType.MatchBool;
  key: KeyBool<T>;
  value: boolean;
  isMatch?: boolean;
};

/** 完全匹配枚举 */
export type ConditionMatchEnum<T> = {
  type: ConditionType.MatchEnum;
  key: KeyAccumulatable<T>;
  value: INTEGER_PG | SMALLINT_PG;
  isMatch?: boolean;
};
export type ConditionMatchEnumOrs<T> = {
  type: ConditionType.MatchEnumOrs;
  key: KeyAccumulatable<T>;
  value: (INTEGER_PG | SMALLINT_PG)[];
  isMatch?: boolean;
};

/** 完全匹配数字 */
export type ConditionMatchInteger<T> = {
  type: ConditionType.MatchInteger;
  key: KeyAccumulatable<T>;
  value: INTEGER_PG;
  isMatch?: boolean;
};
export type ConditionMatchIntegerOrs<T> = {
  type: ConditionType.MatchIntegerOrs;
  key: KeyAccumulatable<T>;
  value: INTEGER_PG[];
  isMatch?: boolean;
};

export enum Sortable {
  NONE = 0,
  /** 从小到大升序 */
  ASC = 1,
  /** 从大到小降序 */
  DESC = -1,
}

/** 按数值排序 */
export type ConditionSort<T> = {
  type: ConditionType.Sort;
  key: KeySortable<T>;
  value: Sortable;
  isMatch?: boolean;
};

export type TimeFilter = {
  startTime: BIGINT_PG;
  endTime: BIGINT_PG;
};

/** 筛选时间 */
export type ConditionTime<T> = {
  type: ConditionType.Time;
  key: KeyBigInt<T>;
  value: TimeFilter;
  isMatch?: boolean;
};

export type KeyAll<T> = KeyBool<T> | KeyAccumulatable<T> | KeyString<T> | KeySortable<T> | KeyBigInt<T>;
export type ConditionAll<T> =
  | ConditionMatchStr<T>
  | ConditionMatchStrOrs<T>
  | ConditionMatchBool<T>
  | ConditionMatchEnum<T>
  | ConditionMatchEnumOrs<T>
  | ConditionMatchInteger<T>
  | ConditionMatchIntegerOrs<T>
  | ConditionRegExpStr<T>
  | ConditionSort<T>
  | ConditionTime<T>;
export type ConditionList<T> = ConditionAll<T>[];
